import deviceManager from '@ohos.distributedDeviceManager';
import Logger from '../util/Logger';

const TAG: string = 'RemoteDeviceModel';
let subscribeId: number = 100;

export class RemoteDeviceModel {
  public certifiedList: Array<deviceManager.DeviceBasicInfo> = [];
  public discoverList: Array<deviceManager.DeviceBasicInfo> = [];
  public callback: () => void;
  public authCallback: () => void;
  public deviceManager: deviceManager.DeviceManager;

  constructor() {
  };

  registerDeviceListCallback(callback) {
    if (typeof (this.deviceManager) !== 'undefined') {
      this.registerDeviceListCallbackImplement(callback);
      return;
    }
    Logger.info(TAG, `gonangtest deviceManager.createDeviceManager begin`);
    try {
      this.deviceManager = deviceManager.createDeviceManager("com.samples.gobang");
      this.registerDeviceListCallbackImplement(callback);
      Logger.info(TAG, `gobangtest createDeviceManager callback returned, value= ${JSON.stringify(this.deviceManager)}`);
    } catch (err) {
      Logger.error(TAG, `gobangtest createDeviceManager failed, code is ${err.code}, message is ${err.message}`);
    }
    Logger.info(TAG, `deviceManager.createDeviceManager end`);
  }

  deviceStateChangeActionOffline(device) {
    if (this.certifiedList.length <= 0) {
      this.callback();
      return;
    }
    for (let j = 0; j < this.certifiedList.length; j++) {
      if (this.certifiedList[j].deviceId === device.deviceId) {
        this.certifiedList[j] = device;
        break;
      }
    }
    Logger.info(TAG, `offline, device list= ${JSON.stringify(this.certifiedList)}`);
    this.callback();
  }

  registerDeviceListCallbackImplement(callback) {
    Logger.info(TAG, `registerDeviceListCallback`);
    this.callback = callback;
    if (this.deviceManager === undefined) {
      Logger.info(TAG, `deviceManager has not initialized`);
      this.callback();
      return;
    }
    ;
    Logger.info(TAG, `getTrustedDeviceListSync begin`);
    try {
      let list = this.deviceManager.getAvailableDeviceListSync();
      Logger.info(TAG, `getTrustedDeviceListSync end, certifiedList= ${JSON.stringify(list)}`);
      if (typeof (list) !== 'undefined' && typeof (list.length) !== 'undefined') {
        this.certifiedList = list;
      }
    } catch (err) {
      Logger.error(`getTrustedDeviceListSync failed, code is ${err.code}, message is ${err.message}`);
    }
    this.callback();
    Logger.info(TAG, `callback finished`);
    this.deviceManager.on('deviceStateChange', (data) => {
      if (data === null) {
        return;
      }
      Logger.info(TAG, `deviceStateChange data= ${JSON.stringify(data)}`);
    })
    this.deviceManager.on('discoverSuccess', (data) => {
      if (data === null) {
        return;
      }
      Logger.info(TAG, `deviceFound data= ${JSON.stringify(data)}`);
      this.deviceFound(data);
    })
    this.deviceManager.on('discoverFailure', (data) => {
      Logger.info(TAG, `discoverFail data= ${JSON.stringify(data)}`);
    });
    this.deviceManager.on('serviceDie', () => {
      Logger.info(TAG, `serviceDie`);
    });
    this.startDeviceDiscovery();
  }

  deviceFound(data) {
    for (var i = 0; i < this.discoverList.length; i++) {
      if (this.discoverList[i].deviceId === data.device.deviceId) {
        Logger.info(TAG, `device founded ignored`);
        return;
      }
    }
    this.discoverList[this.discoverList.length] = data.device;
    Logger.info(TAG, `deviceFound self.discoverList= ${this.discoverList}`);
    this.callback();
  }

  startDeviceDiscovery() {
    Logger.info(TAG, 'startDeviceDiscovery entry');
    try {
      let discoverParam = {
        'discoverTargetType': 1
      };
      let filterOptions: Record<string, number> = {
        'authenticationStatus': 0
      };
      try {
        this.deviceManager.stopDiscovering();
      } catch (e) {
        Logger.error(TAG, 'startDeviceDiscovery to stopDiscovering not find');
      }
      this.deviceManager.startDiscovering(discoverParam, filterOptions);
    } catch (err) {
      Logger.error(TAG, `startDeviceDiscovery failed, code is ${err.code}, message is ${err.message}`);
    }
  }

  unregisterDeviceListCallback() {
    Logger.info(TAG, `stopDeviceDiscovery $subscribeId}`);
    try {
      this.deviceManager.stopDiscovering();
    } catch (err) {
      Logger.error(TAG, `stopDeviceDiscovery failed, code is ${err.code}, message is ${err.message}`);
    }
    this.deviceManager.off('deviceStateChange');
    this.deviceManager.off('discoverSuccess');
    this.deviceManager.off('discoverFailure');
    this.deviceManager.off('serviceDie');
    this.certifiedList = [];
    this.discoverList = [];
  }

  authenticateDevice(device, callBack) {
    Logger.info(TAG, `authenticateDevice ${JSON.stringify(device)}`);
    let bindParam = {
      "bindType": 1,
      "targetPkgName": "com.samples.gobang",
      "appName": "gobang"
    };
    try {
      this.deviceManager.bindTarget(device.deviceId, bindParam, (err, data) => {
        if (err) {
          Logger.error(TAG, `authenticateDevice to bindTarget fail err: ${JSON.stringify(err)}`);
          this.authCallback = null;
          return;
        }
        Logger.info(TAG, `authenticateDevice to bindTarget succeed: ${JSON.stringify(data)}`);
        this.authCallback = callBack;
      });
    } catch (err) {
      callBack();
      Logger.error(TAG, `authenticateDevice failed, code is ${err.code}, message is ${err.message}`);
      return;
    }
  }
}